Amazon API Gateway REST API のパスパラメーターでスラッシュを含む値を指定できるか試してみた(できなかった)
こんにちは、CX事業本部 Delivery部の若槻です。
今回は、Amazon API Gateway REST API で、パスパラメーターにスラッシュ(/
)を含む値を指定できるのか確認する必要があったため、実際に試してみました。
試してみた
実装
AWS CDK で API Gateway REST API を作成し、book_id
パスパラメーターを持つ books
リソースを追加します。
import { Construct } from 'constructs'; import { aws_lambda_nodejs, aws_apigateway, Stack, StackProps, } from 'aws-cdk-lib'; export class CdkSampleStack extends Stack { constructor(scope: Construct, id: string, props: StackProps) { super(scope, id, props); const hogeFunc = new aws_lambda_nodejs.NodejsFunction(this, 'hogeFunc'); const api = new aws_apigateway.RestApi(this, 'books-api'); const books = api.root.addResource('books', {}); const book = books.addResource('{book_id}'); book.addMethod('GET', new aws_apigateway.LambdaIntegration(hogeFunc)); } }
books
リソースのGETメソッドのインテグレーションとして、リクエストのイベントのbook_id
パスパラメーターの値をパースして、レスポンスボディで返すだけの関数を作成します。簡単のためバリデーションなどは付けていません。
interface Event { pathParameters?: { book_id: string; }; } export const handler = async ( event: Event ): Promise<{ statusCode: number; body?: string }> => { console.log(JSON.stringify(event, undefined, 2)); const path = event.pathParameters; const book_id = path?.book_id; return { statusCode: 200, body: JSON.stringify({ book_id }), }; };
動作確認
API Gateway のマネジメントコンソールからメソッドテストを利用して動作確認をしてみます。
スラッシュなしの場合
まず、スラッシュの含まれていないbook01
という値を指定すると、正常にパスパラメーターの値が取得できました。
Lambda 関数のイベントログでも、ちゃんとパスパラメーターの値が取得できていることが確認できます。
スラッシュありの場合
次に、今回試したかったスラッシュが含まれている/path/to/book01
という値を指定してみると、パスパラメーターの値が正常に取得できませんでした。
イベントログを見ると、パスパラメーターの値がnull
となっており、REST API で上手くパース出来ていないようです。
考えられる対処方法
いくつか対処方法はあると思いますが、今回は以下の方法を試してみました。
パスパラメーターに指定する値をエンコードする
REST API へのリクエスト時にスラッシュなどの特殊文字を他の値にエンコードするようにしてみます。
エンコード方法は色々あると思いますが、今回は JavaScript の encodeURIComponent() および decodeURIComponent() 関数を利用してみます。encodeURIComponent は、URI に含まれる特定の文字を UTF-8 文字エンコーディングで表されたエスケープシーケンスに置き換えを行います。
Lambda 側でパスパラメーターから取得したbook_id
パスの値をdecodeURIComponent()
でデコードするようにします。
export const handler = async ( event: Event ): Promise<{ statusCode: number; body?: string }> => { console.log(JSON.stringify(event, undefined, 2)); const path = event.pathParameters; const book_id = decodeURIComponent(path?.book_id!); return { statusCode: 200, body: JSON.stringify({ book_id }), }; };
そして、REST API のマネジメントコンソールからメソッドテストを利用して動作確認をしてみます。
encodeURIComponent()
でエンコード値を作成します。
> encodeURIComponent('/path/to/book01') '%2Fpath%2Fto%2Fbook01'
エンコード値をパスパラメーターに指定してリクエストを送信すると、エンコード前の値をレスポンスで取得できました。
おわりに
Amazon API Gateway REST API のパスパラメーターでスラッシュを含む値を指定できるか試してみました。
結論としてはできなかったため、リクエスト送信時に値をエンコードするなどの対処方法を取る必要がありました。
以上